import { IPackNifi } from "src/inter";
import Nifi from "src/nifi";
import markup from "./markup"
import { pickData, diff } from "../../util"
import FormElem from "./form.vue"
import ContextmenuElem from "./contextmenu.vue"
import { h } from "vue";
import { Edge } from "@ui/pack-antv-x6";
import { ElMessage } from "element-plus";
import { DEFAULT_CELL_NAME } from "../metadata";
import {t} from "../../i18n/index"

const KEYS: [key: string, sk?: any][] = [
    ['id'],
    ['label', ['component.name', 'status.name','component.source.name']],
    // 由于 label 无法触发 propsHooks 所以添加一个额外属性 text 
    ['text', ['component.name', 'status.name']],
    ['quene', 'status.aggregateSnapshot.queuedCount'],
    ['byte', 'status.aggregateSnapshot.queuedSize'],
    ['precent', 'status.aggregateSnapshot.percentUseCount'],
    ['bytePrecent', 'status.aggregateSnapshot.percentUseBytes'],
    ['version', 'revision.version']
];

const name = DEFAULT_CELL_NAME.connections.en;
const shape = `c-${name}`
export default (nifi: Nifi) => {

    // 注册 edge
    nifi.graph.registerEdge(shape, markup)
    // 注册事件
    nifi.graph.onMounted((graph) => {
        graph.on('edge:connected', ({ edge }) => {
            graph.removeCell(edge);
            nifi.drawer.open(h(FormElem, { nifi, cell: edge }) as any)
        })
    })
    // 初始化 返回 元素 metadata
    const init = (tds: any[] = [], mds: any[] = []) => {
        return tds.map(td => {
            //
            nifi.cells.set(td);
            //
            const md: any = { name, shape, ...pickData(td, KEYS) };
            //
            const sid = td.sourceGroupId != nifi.group.id ? td.sourceGroupId : td.sourceId;
            const tid = td.destinationGroupId != nifi.group.id ? td.destinationGroupId : td.destinationId;
            const smd = mds.find(d => d.id == sid)
            const tmd = mds.find(d => d.id == tid)
            const sport = smd?.ports?.items?.[1]?.id
            const tport = tmd?.ports?.items?.[0]?.id
            md.source = { port: sport, cell: sid }
            md.target = { port: tport, cell: tid }
            md.status = smd.status;
            //
            return md;
        })
    }

    const getLabel = (cell: IPackNifi.SC) => {
        const data = nifi.cells.get(cell);
        //
        return data?.status?.name;
    }
    // 获取状态
    const getStatus = (cell: IPackNifi.SC) => {
        const data = nifi.cells.get(cell);
        const sid = data.status.sourceId;
        const sd = nifi.cells.get(sid);
        return sd.status.runStatus;
    }
    // 获取数据
    const getData = (cell: IPackNifi.SC) => {
        const data = nifi.cells.get(cell);
        const { queuedCount, queuedSize, percentUseCount, percentUseBytes } = data.status.aggregateSnapshot;
        const quene = queuedCount;
        const byte = `(${queuedSize})`
        const precent = percentUseCount + percentUseBytes - percentUseBytes;
        return { quene, byte, precent }
    }

    // 编辑边 弹出 表单抽屉

    // 获取表单所需的数据
    const getForm = (cell: IPackNifi.SC) => {

    }
    // 新增边数据和渲染
    const add = (td: any, edge: Edge) => {
        const { source, target } = edge.prop();
        const md = { source, target, name, shape, id: td.id };
        //
        nifi.graph?.addEdge(md);
        update(td)
    }
    // 更新元素数据
    const update = (td: any) => {
        const { revision, id } = td;
        const sd = nifi.cells.get(id);
        nifi.cells.set(td)
        const props = diff(pickData(td, KEYS), pickData(sd, KEYS))
        if (sd && revision.version == sd.revision.version && props == undefined) {
            console.info('=========== 没有发现版本和数据变化 无需更新节点属性 ============')
            return false;
        }
        //
        
        //
        if (props && Object.keys(props).length > 0) {
            const sid = td.sourceGroupId != nifi.group.id ? td.sourceGroupId : td.sourceId;
            props.status = nifi.graph?.getCellById(sid).prop('status');
            //
            nifi.graph.getCellById(id).prop(props)
        }
    }

    const updateData = (e: IPackNifi.SC) => {
        const id = typeof e == 'string' ? e : e.id;
        const edges = nifi.graph?.getEdges() || [];
        for (const t of edges) {
            if (t.getSourceCellId() === id) {
                refresh(t);
            }
        }
    }

    // 更新一个节点所有出边的状态
    const updateStatus = (e: IPackNifi.SC) => {
        const cell = typeof e === 'string' ? nifi.graph?.getCellById(e) : e;
        //
        const status = cell?.prop('status');
        if (cell && status) {
            const id = cell.id;
            const edges = nifi.graph?.getEdges() || [];
            for (const t of edges) {
                if (t.getSourceCellId() === id) {
                    t.prop({ status })
                }
            }
        }
    }
    // 刷新元素
    const refresh = async (cell: Edge) => {
        try {
            const res = await nifi.cells.getCell(cell);
            update(res);
            return true;
        } catch (error) {
            ElMessage.error("更新边失败 :: " + error)
            console.error(error)
            return false;
        }
    }

    // 编辑
    const edit = async (cell: Edge) => {
        nifi.drawer.open();
        await refresh(cell)
        const vnode: any = h(FormElem, { nifi, cell })
        nifi.drawer.set(vnode);
    }

    const view = async (cell: Edge) => {
        nifi.drawer.open();
        await refresh(cell)
        const vnode: any = h(FormElem, { nifi, cell, disabled: true })
        nifi.drawer.set(vnode);
    }

    // 右键菜单
    const contextmenu = (cell: Edge, evt: MouseEvent) => {
        const vnode: any = h(ContextmenuElem, { cell, nifi })
        nifi.contextmenu.open(evt, vnode)
    };
    
    // 列出队列

    return {
        name,
        init,
        add,
        // 刷新边
        refresh,
        // 更新数据
        update,
        // 当节点状态变更时，更新节点的边的状态
        updateStatus,
        // 当节点数据
        updateData,
        // 编辑边
        edit,
        view,
        // 右键菜单
        contextmenu,
    }

}